package ikar.view.components;

import ikar.nrd.fillingref.generator.CoreUtils;
import ikar.nrd.model.FillingRefTreeModelFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.extensions.markup.html.tabs.PanelCachingTab;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.lang.Bytes;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.ValidationError;
import org.apache.wicket.validation.validator.StringValidator;
import org.w3c.dom.Document;

/**
 * Homepage
 */
public class HomePage extends WebPage {

	private static final long serialVersionUID = 1L;
	private final Form<?> mainForm;
	private FormTabbedPanel tabPanel;
	private FileUploadField fileUpload;
	private TextField<String> patternId;
	private TextField<String> xsdElementType;
	private TextField<String> xmlElementName;
	private PanelCachingTab xmlSchemaTab;
	private AbstractTab xsltInTab;
	private AbstractTab xsltOutTab;
	private AbstractTab scriptsTab;
	private DefaultTreeModel model;
	private CheckBox useXsdChBx;

	public HomePage() {


		add(new FeedbackPanel("feedback") {
			private static final long serialVersionUID = 1L;

			@Override
			protected void onConfigure() {
				setVisible(anyMessage(FeedbackMessage.ERROR));
			}
		});
		mainForm = new Form<Void>("form") {
			private static final long serialVersionUID = 1L;

			@Override
			protected void onSubmit() {
				super.onSubmit();
				final FileUpload uploadedFile = fileUpload.getFileUpload();

				try {
					if (useXsdChBx.getModelObject() == true && !Strings.isEmpty(xsdElementType.getValue())) {
						FillingRefTreeModelFactory fillRefModelFactory = new FillingRefTreeModelFactory();
						model = (DefaultTreeModel) fillRefModelFactory.createTreeModelFromXsd(xsdElementType.getValue(), xmlElementName.getValue(), patternId.getValue());
						updateTabs();
					}
					else if (uploadedFile != null) {
						if (uploadedFile.getClientFileName().endsWith("xml")) {
							Document xmlDocument = CoreUtils.getXmlDocument(uploadedFile.getInputStream());
							FillingRefTreeModelFactory fillRefModelFactory = new FillingRefTreeModelFactory();
							model = (DefaultTreeModel) fillRefModelFactory.createTreeModelFromXml(xmlDocument, patternId.getValue());
							updateTabs();
						}
					}
					// createTreeModelFromXsd();

				} catch (Throwable th) {

				}
			}

		};
		CollapsibleBorder border = new CollapsibleBorder("border", Model.of("- load instrument -"), Model.of("+ load instrument +"));
		add(mainForm);
		mainForm.add(border);
		border.setCollapsed(true);

		mainForm.setMultiPart(true);
		mainForm.setMaxSize(Bytes.kilobytes(1000));

		border.getBodyContainer().add(fileUpload = new FileUploadField("fileUpload"));
		border.getBodyContainer().add(patternId = new TextField<String>("patternId", Model.of("")));
		border.getBodyContainer().add(xsdElementType = new TextField<String>("xsdElementType", Model.of("")));
		border.getBodyContainer().add(xmlElementName = new TextField<String>("xmlElementName", Model.of("")));
		border.getBodyContainer().add(useXsdChBx = new CheckBox("useXsd", Model.of(new Boolean(false))));

		mainForm.add(new StringValidator() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void onValidate(IValidatable<String> arg0) {
				if (arg0.getValue() == null || arg0.getValue().length() == 0) {
					ValidationError error = new ValidationError();
					error.setMessage("PatternId value can't be empty!");
					arg0.error(new ValidationError());
				}

			}
		});
		mainForm.add(new FormTabbedPanel("tabs", new ArrayList<ITab>()));
	}

	private void updateTabs() {
		if (model != null) {
			setResponsePage(getPage());
			removeTabs(mainForm);
			initTabs();
			addTabs(mainForm);
			this.setOutputMarkupId(true);
			useXsdChBx.setModelObject(false);
			useXsdChBx.setOutputMarkupId(true);
		}
	}

	private void initTabs() {
		xmlSchemaTab = new PanelCachingTab(new AbstractTab(new Model("XML Source Schema")) {
			@Override
			public Panel getPanel(String panelId) {
				return new EditableTreeGridPanel(panelId, model) {
					@Override
					public boolean isEnabled() {
						return model != null;
					}
				};
			}
		});
		scriptsTab = new AbstractTab(new Model("Date Base Scripts")) {

			@Override
			public Panel getPanel(String panelId) {
				return new FillingRefDataBaseScriptPanel(panelId, (DefaultMutableTreeNode) model.getRoot()) {
					@Override
					public boolean isEnabled() {
						return model != null;
					}
				};
			}
		};

		xsltOutTab = new AbstractTab(new Model("XSL Out Transform")) {

			@Override
			public Panel getPanel(String panelId) {
				return new XslOutTransformPanel(panelId, xmlElementName.getValue(), (DefaultMutableTreeNode) model.getRoot()) {
					@Override
					public boolean isEnabled() {
						return model != null;
					}
				};
			}
		};

		xsltInTab = new AbstractTab(new Model("XSL In Transform")) {

			@Override
			public Panel getPanel(String panelId) {
				return new XslInTrasformPanel(panelId, (DefaultMutableTreeNode) model.getRoot()) {
					@Override
					public boolean isEnabled() {
						return model != null;
					}
				};
			}
		};
	}

	private void addTabs(Form<?> form) {
		List<ITab> tabs = Arrays.asList(xmlSchemaTab, scriptsTab, xsltInTab, xsltOutTab);
		tabPanel = new FormTabbedPanel("tabs", tabs);
		form.add(tabPanel);
	}

	private void removeTabs(Form<?> form) {
		if (tabPanel != null) {
			tabPanel.removeAll();
		}
		form.remove("tabs");
	}

}
